1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing.testers;
18
19 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22 import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
24 import static java.util.Collections.singletonList;
25
26 import com.google.common.annotations.GwtCompatible;
27 import com.google.common.collect.testing.AbstractMapTester;
28 import com.google.common.collect.testing.MinimalCollection;
29 import com.google.common.collect.testing.features.CollectionSize;
30 import com.google.common.collect.testing.features.MapFeature;
31
32 import java.util.Collections;
33 import java.util.ConcurrentModificationException;
34 import java.util.Iterator;
35 import java.util.LinkedHashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Map.Entry;
39
40
41
42
43
44
45
46
47
48 @SuppressWarnings("unchecked")
49 @GwtCompatible(emulated = true)
50 public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
51 private List<Entry<K, V>> containsNullKey;
52 private List<Entry<K, V>> containsNullValue;
53
54 @Override public void setUp() throws Exception {
55 super.setUp();
56 containsNullKey = singletonList(entry(null, samples.e3.getValue()));
57 containsNullValue = singletonList(entry(samples.e3.getKey(), null));
58 }
59
60 @MapFeature.Require(SUPPORTS_PUT)
61 public void testPutAll_supportedNothing() {
62 getMap().putAll(emptyMap());
63 expectUnchanged();
64 }
65
66 @MapFeature.Require(absent = SUPPORTS_PUT)
67 public void testPutAll_unsupportedNothing() {
68 try {
69 getMap().putAll(emptyMap());
70 } catch (UnsupportedOperationException tolerated) {
71 }
72 expectUnchanged();
73 }
74
75 @MapFeature.Require(SUPPORTS_PUT)
76 public void testPutAll_supportedNonePresent() {
77 putAll(createDisjointCollection());
78 expectAdded(samples.e3, samples.e4);
79 }
80
81 @MapFeature.Require(absent = SUPPORTS_PUT)
82 public void testPutAll_unsupportedNonePresent() {
83 try {
84 putAll(createDisjointCollection());
85 fail("putAll(nonePresent) should throw");
86 } catch (UnsupportedOperationException expected) {
87 }
88 expectUnchanged();
89 expectMissing(samples.e3, samples.e4);
90 }
91
92 @MapFeature.Require(SUPPORTS_PUT)
93 @CollectionSize.Require(absent = ZERO)
94 public void testPutAll_supportedSomePresent() {
95 putAll(MinimalCollection.of(samples.e3, samples.e0));
96 expectAdded(samples.e3);
97 }
98
99 @MapFeature.Require({ FAILS_FAST_ON_CONCURRENT_MODIFICATION,
100 SUPPORTS_PUT })
101 @CollectionSize.Require(absent = ZERO)
102 public void testPutAllSomePresentConcurrentWithEntrySetIteration() {
103 try {
104 Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
105 putAll(MinimalCollection.of(samples.e3, samples.e0));
106 iterator.next();
107 fail("Expected ConcurrentModificationException");
108 } catch (ConcurrentModificationException expected) {
109
110 }
111 }
112
113 @MapFeature.Require(absent = SUPPORTS_PUT)
114 @CollectionSize.Require(absent = ZERO)
115 public void testPutAll_unsupportedSomePresent() {
116 try {
117 putAll(MinimalCollection.of(samples.e3, samples.e0));
118 fail("putAll(somePresent) should throw");
119 } catch (UnsupportedOperationException expected) {
120 }
121 expectUnchanged();
122 }
123
124 @MapFeature.Require(absent = SUPPORTS_PUT)
125 @CollectionSize.Require(absent = ZERO)
126 public void testPutAll_unsupportedAllPresent() {
127 try {
128 putAll(MinimalCollection.of(samples.e0));
129 } catch (UnsupportedOperationException tolerated) {
130 }
131 expectUnchanged();
132 }
133
134 @MapFeature.Require({SUPPORTS_PUT,
135 ALLOWS_NULL_KEYS})
136 public void testPutAll_nullKeySupported() {
137 putAll(containsNullKey);
138 expectAdded(containsNullKey.get(0));
139 }
140
141 @MapFeature.Require(value = SUPPORTS_PUT,
142 absent = ALLOWS_NULL_KEYS)
143 public void testPutAll_nullKeyUnsupported() {
144 try {
145 putAll(containsNullKey);
146 fail("putAll(containsNullKey) should throw");
147 } catch (NullPointerException expected) {
148 }
149 expectUnchanged();
150 expectNullKeyMissingWhenNullKeysUnsupported(
151 "Should not contain null key after unsupported " +
152 "putAll(containsNullKey)");
153 }
154
155 @MapFeature.Require({SUPPORTS_PUT,
156 ALLOWS_NULL_VALUES})
157 public void testPutAll_nullValueSupported() {
158 putAll(containsNullValue);
159 expectAdded(containsNullValue.get(0));
160 }
161
162 @MapFeature.Require(value = SUPPORTS_PUT,
163 absent = ALLOWS_NULL_VALUES)
164 public void testPutAll_nullValueUnsupported() {
165 try {
166 putAll(containsNullValue);
167 fail("putAll(containsNullValue) should throw");
168 } catch (NullPointerException expected) {
169 }
170 expectUnchanged();
171 expectNullValueMissingWhenNullValuesUnsupported(
172 "Should not contain null value after unsupported " +
173 "putAll(containsNullValue)");
174 }
175
176 @MapFeature.Require(SUPPORTS_PUT)
177 public void testPutAll_nullCollectionReference() {
178 try {
179 getMap().putAll(null);
180 fail("putAll(null) should throw NullPointerException");
181 } catch (NullPointerException expected) {
182 }
183 }
184
185 private Map<K, V> emptyMap() {
186 return Collections.emptyMap();
187 }
188
189 private void putAll(Iterable<Entry<K, V>> entries) {
190 Map<K, V> map = new LinkedHashMap<K, V>();
191 for (Entry<K, V> entry : entries) {
192 map.put(entry.getKey(), entry.getValue());
193 }
194 getMap().putAll(map);
195 }
196 }
197